<?php
// 批量导入处罚规则
namespace Beerus\Modules\Violation\Actions;

use Doraemon\model\DesignerAuth;
use Doraemon\pockets\excel\ReadExcel;
use Doraemon\service\Designer\DesignerViolationRecord;
use Doraemon\tools\Log;
use Doraemon\tools\ParamsCheck;
use Encore\Admin\Actions\Action;
use Illuminate\Http\Request;

class ImportViolation extends Action{
    public $name = '批量导入';

    protected $selector = '.import-post';

    const PUNISH_TYPE_LIST = [
        DesignerViolationRecord::PUNISH_TYPE_WARNING,
        DesignerViolationRecord::PUNISH_TYPE_RECOMMEND_SCORE,
        DesignerViolationRecord::PUNISH_TYPE_UNRECOMMENDED,
        DesignerViolationRecord::PUNISH_TYPE_LIST_SEE,
        DesignerViolationRecord::PUNISH_TYPE_OFF,
        DesignerViolationRecord::PUNISH_TYPE_CANCEL_AUTHENTICATION,
        DesignerViolationRecord::PUNISH_TYPE_NOT_ALLOW_RENEW
    ];

    const NEED_POSITIVE_PUNISH_TYPE_LIST = [ // 需要大于0的天数
        DesignerViolationRecord::PUNISH_TYPE_OFF,
        DesignerViolationRecord::PUNISH_TYPE_LIST_SEE,
        DesignerViolationRecord::PUNISH_TYPE_UNRECOMMENDED,
    ];

    const DIMENSION_TYPE = [
        DesignerViolationRecord::RECOMMEND_SCORE_DIMENSION_EVALUATE,
        DesignerViolationRecord::RECOMMEND_SCORE_DIMENSION_APPROVE,
        DesignerViolationRecord::RECOMMEND_SCORE_DIMENSION_ACTIVE,
        DesignerViolationRecord::RECOMMEND_SCORE_DIMENSION_POPULARITY,
        DesignerViolationRecord::RECOMMEND_SCORE_DIMENSION_PUBLISH,
    ];

    const PUNISH_TYPE_TEXT_ACCESS_INDEX = [
        '警告' => DesignerViolationRecord::PUNISH_TYPE_WARNING,
        '推荐指数' => DesignerViolationRecord::PUNISH_TYPE_RECOMMEND_SCORE,
        '平台不推荐' => DesignerViolationRecord::PUNISH_TYPE_UNRECOMMENDED,
        '仅列表可见' => DesignerViolationRecord::PUNISH_TYPE_LIST_SEE,
        '下架' => DesignerViolationRecord::PUNISH_TYPE_OFF,
        '取消认证' => DesignerViolationRecord::PUNISH_TYPE_CANCEL_AUTHENTICATION,
        '不予续费' => DesignerViolationRecord::PUNISH_TYPE_NOT_ALLOW_RENEW,
    ];
    const DIMENSION_TEXT_ASSOC_INDEX = [
        '口碑分' => DesignerViolationRecord::RECOMMEND_SCORE_DIMENSION_EVALUATE,
        '认可分' => DesignerViolationRecord::RECOMMEND_SCORE_DIMENSION_APPROVE,
        '活跃分' => DesignerViolationRecord::RECOMMEND_SCORE_DIMENSION_ACTIVE,
        '人气分' => DesignerViolationRecord::RECOMMEND_SCORE_DIMENSION_POPULARITY,
        '发布分' => DesignerViolationRecord::RECOMMEND_SCORE_DIMENSION_PUBLISH,
    ];

    public function handle(Request $request) {
        $oFile = $request->file('file');
        $newFile = 'violation.xls';
        $newFilePath = '/tmp/'.$newFile;
        $rs = move_uploaded_file($oFile, $newFilePath);
        if (!$rs) {
            return $this->response()->error("上传错误");
        }
        $oExcel = new ReadExcel($newFile);
        try {
            $aExcelRawData = $oExcel->getExcelDataNoHeader($newFilePath);
        } catch (\PHPExcel_Reader_Exception $exception) {
            return $this->response()->error("上传错误");
        }
        $aViolationData = [];
        $iViolationLength = count($aExcelRawData);
        for ($i = 1; $i < $iViolationLength; $i ++) {
            // 第一列是用户uid，第二列是违规原因
            // 每个uid是一条记录，uid有多个处罚时，分开记录
            $iUid = $aExcelRawData[$i][0];
            $sViolationReason = $aExcelRawData[$i][1];
            $iPunishType = self::PUNISH_TYPE_TEXT_ACCESS_INDEX[$aExcelRawData[$i][2]];
            $sPunishStartDate = $aExcelRawData[$i][3];
            $iPunishUnit = $aExcelRawData[$i][4];// 处罚天数
            $iDimension = self::DIMENSION_TEXT_ASSOC_INDEX[$aExcelRawData[$i][5]];// 扣除推荐指数分数的纬度
            // 检查数据是否正确
            if (!in_array($iPunishType, self::PUNISH_TYPE_LIST)) {
                return $this->response()->error("UID:{$iUid}-处罚类型不合法");
            }
            // 如果不是警告的处罚类型，开始时间不是空，则日期判断格式是否合法
            if ($iPunishType != DesignerViolationRecord::PUNISH_TYPE_WARNING && !empty($sPunishStartDate)) {
                list($iYear, $iMonth, $iDay) = explode('-', $sPunishStartDate);
                if (!checkdate($iMonth, $iDay, $iYear)) {
                    return $this->response()->error("UID:{$iUid}-处罚开始时间不合法");
                }
            }
            // 开始时间是空的话默认当天日期
            if ($iPunishType != DesignerViolationRecord::PUNISH_TYPE_WARNING && empty($sPunishStartDate)) {
                $sPunishStartDate = date('Y-m-d');
            }
            // 判断推荐指数相关参数
            if ($iPunishType == DesignerViolationRecord::PUNISH_TYPE_RECOMMEND_SCORE) {
                if (!in_array($iPunishUnit, DesignerViolationRecord::RECOMMEND_SCORE_LEVEL_LIST)) {
                    return $this->response()->error("UID:{$iUid}-扣减分数不合法");
                }
                if (!in_array($iDimension, self::DIMENSION_TYPE)) {
                    return $this->response()->error("UID:{$iUid}-扣减纬度不合法");
                }
            }
            // 判断需要结束时间的处罚天数是否合法
            if (in_array($iPunishType, self::NEED_POSITIVE_PUNISH_TYPE_LIST) && $iPunishUnit <= 0) {
                return $this->response()->error("UID:{$iUid}-处罚天数不合法");
            }
            $designerAuthInfo = DesignerAuth::getByUId($iUid);
            if ($designerAuthInfo['designer_type'] == DesignerAuth::DESIGNER_TYPE_COMPANY) {
                $designerAuthUpdateKey = 'business_license_number';
            } else {
                $designerAuthUpdateKey = 'id_card_number';
            }
            $aViolationData[] = [
                'uid' => $iUid,
                'violation_reason' => $sViolationReason,
                'identity_number' => $designerAuthInfo[$designerAuthUpdateKey],
                'punish_type' => $iPunishType,
                'punish_start_date' => $sPunishStartDate,
                'dimension' => $iDimension,
                'punish_unit' => $iPunishUnit
            ];
        }
        if (!empty($aViolationData)) {
            foreach ($aViolationData as $aViolationItem) {
                $iUid = $aViolationItem['uid'];
                $sViolationReason = $aViolationItem['violation_reason'];
                $sIdentityNumber = $aViolationItem['identity_number'];
                $aPunishList = [
                    [
                        'is_punish' => 1,
                        'punish_type' => $aViolationItem['punish_type'],
                        'punish_start_date' => $aViolationItem['punish_start_date'],
                        'dimension' => $aViolationItem['dimension'],
                        'punish_unit' => $aViolationItem['punish_unit']
                    ]
                ];
                if (!DesignerViolationRecord::addViolationRecord($iUid, $sViolationReason, $aPunishList, $sIdentityNumber, '系统', false)) {
                    $aFailUidInfo[] = [
                        'uid' => $iUid,
                        'punish_type' => $aViolationItem['punish_type'],
                        'punish_start_date' => $aViolationItem['punish_start_date'],
                        'dimension' => $aViolationItem['dimension'],
                        'punish_unit' => $aViolationItem['punish_unit']
                    ];
                }
            }
        }
        if (!empty($aFailUidInfo)) {
            $sMsg = "以下记录保存失败，请剔除成功的记录后再重新导入，或联系功能负责人\n";
            foreach ($aFailUidInfo as $iFailUidItem) {
                $sMsg .= 'UID:' . $iFailUidItem['uid']
                    . '-违规类型:' . DesignerViolationRecord::PUNISH_TYPE_TXT_LIST[$iFailUidItem['punish_type']]
                    . '-处罚开始时间:' . $iFailUidItem['punish_start_date']
                    . '-推荐指数扣减纬度:' . $iFailUidItem['dimension']
                    . '-处罚天数/分数:' . $iFailUidItem['punish_unit']
                    . "\n";
            }
            Log::error($sMsg);
            return $this->response()->error($sMsg);
        }
        return $this->response()->success('success')->refresh();
    }

    public function form() {
        $this->file('file', '请选择文件');
    }

    public function html() {
        return <<<HTML
<i class="fa fa-plus"></i>
<a class="btn btn-sm btn-success import-post">批量导入</a>
HTML;

    }
}